const express = require('express');
const XlsxPopulate = require('xlsx-populate');
const path = require('path');
const fs = require('fs');
const cors = require('cors');
const multer = require('multer'); // 用于处理文件上传
const { log } = require('console');
const app = express();

app.use(cors());
app.use(express.json());

const templateDir = path.join(__dirname, 'excelTemplates');
if (!fs.existsSync(templateDir)) {
  fs.mkdirSync(templateDir);
}

app.use(express.static(__dirname));



app.post('/excelprocessTp', (req, res) => {
  try {
    // 直接创建可读流（假设文件路径通过请求参数传递）
    const fileName = req.body[0].taxCode + '.xlsx';
    // const filePath = path.join(__dirname, 'excelprocessTp', 'A.xlsx');
    const filePath = path.join(__dirname, 'excelprocessTp', fileName);
    // 创建文件读取流
    const fileStream = fs.createReadStream(filePath);

    // 设置响应头（需根据实际文件名动态设置）
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    
    // 将文件流直接传输到响应对象
    fileStream.pipe(res);

    // 错误处理
    fileStream.on('error', (err) => {
      console.error('文件流发送时出错:', err);
      res.status(500).send('文件流发送时出错');
    });

  } catch (error) {
    console.error('处理文件时出错:', error.message);
    res.status(500).send(`处理文件时出错: ${error.message}`);
  }
});
app.post('/excelprocess', async (req, res) => {
  try {
    const fileName = req.body[0].taxCode + '.xlsx';
    const filePath = path.join(templateDir, fileName);
    if (!fs.existsSync(filePath)) {
      return res.status(404).send(`文件 ${fileName} 不存在`);
    }

    const selectedFile = filePath;
    const fileExtension = path.extname(selectedFile).toLowerCase();
    if (fileExtension !== '.xlsx') {
      return res.status(400).send('仅支持 .xlsx 文件');
    }

    fs.accessSync(selectedFile, fs.constants.R_OK);
    const workbook = await XlsxPopulate.fromFileAsync(selectedFile);
    const modifications = req.body; // 前端传入的数组

    // 根据索引顺序处理工作表
    modifications.forEach((sheetData, sheetIndex) => {
      const sheet = workbook.sheet(sheetIndex); // 通过索引获取工作表

      if (!sheet) {
        console.warn(`警告：第 ${sheetIndex} 个工作表不存在，跳过修改`);
        return;
      }

      // 替换工作表名称
      const newSheetName = sheetData.newSheetName; // 假设前端传入的新名称字段为 newSheetName
      if (newSheetName) {
        try {
          sheet.name(newSheetName); // 修改工作表名称
          console.log(`已将第 ${sheetIndex} 个工作表名称修改为: ${newSheetName}`);
        } catch (e) {
          console.error(`修改工作表名称失败: ${e.message}`);
        }
      } else {
        console.warn(`警告：第 ${sheetIndex} 个工作表缺少 newSheetName 字段，跳过名称修改`);
      }

      // 确保数据字段存在
      const data = sheetData.data;

      if (!data) {
        console.warn(`警告：第 ${sheetIndex} 个工作表缺少 data 字段，跳过单元格修改`);
        return;
      }

      // 应用单元格修改
      for (const [cellAddress, value] of Object.entries(data)) {
        try {
          sheet.cell(cellAddress).value(value);
        } catch (e) {
          console.error(`单元格 ${cellAddress} 修改失败：${e.message}`);
        }
      }
    });

    const outputPath = path.join(__dirname, 'output.xlsx');
    await workbook.toFileAsync(outputPath);

    const originalFileName = req.query.filename || '修改后.xlsx';
    const encodedFileName = encodeURIComponent(originalFileName).replace(/'/g, '%27');

    res.setHeader('Content-Disposition', `attachment; filename="${encodedFileName}"`);
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');

    const fileStream = fs.createReadStream(outputPath);
    fileStream.pipe(res);

    fileStream.on('error', (err) => {
      console.error('文件流发送时出错:', err);
      res.status(500).send('文件流发送时出错');
    });

    fileStream.on('end', () => {
      try {
        if (fs.existsSync(outputPath)) {
          fs.unlinkSync(outputPath);
        }
      } catch (err) {
        console.error('删除临时文件时出错:', err);
      }
    });

  } catch (error) {
    console.error('处理文件时出错:', error.message);
    res.status(500).send(`处理文件时出错: ${error.message}`);
  }
});

app.post('/exceluploadsList', (req, res) => {
  try {
    // 定义目标目录
    const directoryPath = path.join(__dirname, 'uploads');

    // 读取目录中的文件列表
    fs.readdir(directoryPath, (err, files) => {
      if (err) {
        console.error('读取目录时出错:', err);
        return res.status(500).send('读取目录时出错');
      }

      // 确保目录中有文件
      if (files.length === 0) {
        return res.status(404).send('目录中没有文件');
      }

      // 按照修改时间排序，获取最新的文件
      fs.stat(path.join(directoryPath, files[0]), (err, stats) => { // 初始化第一个文件的状态
        if (err) {
          console.error('获取文件状态时出错:', err);
          return res.status(500).send('获取文件状态时出错');
        }

        let latestFile = files[0];
        let latestTime = stats.mtime;

        // 遍历剩余文件，找到最新文件
        for (let i = 1; i < files.length; i++) {
          fs.stat(path.join(directoryPath, files[i]), (err, stats) => {
            if (err) {
              console.error('获取文件状态时出错:', err);
              return res.status(500).send('获取文件状态时出错');
            }

            if (stats.mtime > latestTime) {
              latestFile = files[i];
              latestTime = stats.mtime;
            }
          });
        }

        // 构造最新文件的完整路径
        const latestFilePath = path.join(directoryPath, latestFile);
        console.log(latestFilePath);
        
        // 创建文件读取流
        const fileStream = fs.createReadStream(latestFilePath);

        // 设置响应头（需根据实际文件名动态设置）
        res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        res.setHeader('Content-Disposition', `attachment; filename=${encodeURIComponent(latestFile)}`);

        // 将文件流直接传输到响应对象
        fileStream.pipe(res);

        // 错误处理
        fileStream.on('error', (err) => {
          console.error('文件流发送时出错:', err);
          res.status(500).send('文件流发送时出错');
        });
      });
    });

  } catch (error) {
    console.error('处理文件时出错:', error.message);
    res.status(500).send(`处理文件时出错: ${error.message}`);
  }
});
// Multer 配置
const storage = multer.diskStorage({
  destination: (req, file, cb) => cb(null, 'uploads/'),
  filename: (req, file, cb) => {
    const timestamp = Date.now();
    const cleanName = path.basename(file.originalname, path.extname(file.originalname)).replace(/[^a-zA-Z0-9.-]/g, '');
    // 强制使用 .xlsx 后缀
    const ext = '.xlsx'; 
    cb(null, `${timestamp}-${cleanName}${ext}`);
  }
});

const upload = multer({
  storage,
  limits: { fileSize: 50 * 1024 * 1024 }, // 50MB
  fileFilter: (req, file, cb) => {
    const allowedMimeTypes = ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
    if (allowedMimeTypes.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error('仅支持上传 .xlsx 文件'), false);
    }
  }
});

// 文件上传接口
app.post('/saveexcel', upload.single('file'), (req, res) => {
  if (!req.file) {
    return res.status(400).send('未检测到文件');
  }
  res.json({ 
    code:200,
    message: '文件上传成功', 
    filePath: `/uploads/${req.file.filename}` 
  });
});
const port = 3000;
app.listen(port, () => {
  console.log(`服务器运行在端口 http://localhost:${port}`);
});
